package br.com.ava.core.infra.persistencia;

import java.io.Serializable;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import br.com.ava.core.infra.excecao.NegocioException;

/**
 * Define um Mediator no sistema.
 * 
 * @param <T>
 *            Tipo a ser persistido.
 */
@SuppressWarnings("serial")
public abstract class AbstractMediator<T extends ObjetoPersistente> implements
		Serializable {

	/**
	 * Realiza as valida��es necess�rias para inclus�o e repassa o objeto a ser
	 * persistido para o DAO.
	 * 
	 * @param obj
	 *            Objeto a ser validado e repassado para o DAO.
	 */
	@Transactional(isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
	public void salvar(T obj) {
		validarInclusao(obj);
		getDao().salvar(obj);
	}

	/**
	 * Realiza as valida��es necess�rias para altera��o e repassa o objeto a ser
	 * alterado para o DAO.
	 * 
	 * @param obj
	 *            Objeto a ser validado e repassado para o DAO.
	 */
	@Transactional(isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
	public void alterar(T obj) {
		validarAlteracao(obj);
		getDao().alterar(obj);
	}

	/**
	 * Realiza as valida��es necess�rias para exclus�o e repassa o objeto a ser
	 * exclu�do para o DAO.
	 * 
	 * @param obj
	 *            Objeto a ser validado e repassado para o DAO.
	 */
	public void excluir(T obj) {
		validarExclusao(obj);
		getDao().excluir(obj);
	}

	/**
	 * Recupera o DAO a ser utilizado para realizar a comunica��o com o
	 * mecanismo de persist�ncia.
	 * 
	 * @return DAO a ser utilizado para realizar a comunica��o com o mecanismo
	 *         de persist�ncia.
	 */
	protected abstract AbstractDAO<T> getDao();

	/**
	 * Valida��o realizada antes da inclus�o.
	 * 
	 * @param obj
	 *            Objeto a ser validado.
	 * @throws NegocioException
	 *             Caso alguma valida��o falhe.
	 */
	protected void validarInclusao(T obj) throws NegocioException {
		// Implementado na subclasse caso necess�rio.
	};

	/**
	 * Valida��o realizada antes da altera��o.
	 * 
	 * @param obj
	 *            Objeto a ser validado.
	 * @throws NegocioException
	 *             Caso alguma valida��o falhe.
	 */
	protected void validarAlteracao(T obj) throws NegocioException {
		// Implementado na subclasse caso necess�rio.
	};

	/**
	 * Valida��o realizada antes da exclus�o.
	 * 
	 * @param obj
	 *            Objeto a ser validado.
	 * @throws NegocioException
	 *             Caso alguma valida��o falhe.
	 */
	protected void validarExclusao(T obj) throws NegocioException {
		// Implementado na subclasse caso necess�rio.
	};
}
